package br.com.toscano.contpedido.view;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import javax.inject.Inject;

import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;

import br.com.toscano.contpedido.business.ClienteBC;
import br.com.toscano.contpedido.business.FormaRecebimentoBC;
import br.com.toscano.contpedido.business.PedidoBC;
import br.com.toscano.contpedido.business.RecebimentoBC;
import br.com.toscano.contpedido.business.UsuarioBC;
import br.com.toscano.contpedido.constant.ConstantesMensagem;
import br.com.toscano.contpedido.domain.Cliente;
import br.com.toscano.contpedido.domain.ContextoUsuario;
import br.com.toscano.contpedido.domain.FormaRecebimento;
import br.com.toscano.contpedido.domain.Pedido;
import br.com.toscano.contpedido.domain.Perfil;
import br.com.toscano.contpedido.domain.Recebimento;
import br.com.toscano.contpedido.domain.StatusPedido;
import br.com.toscano.contpedido.domain.Usuario;
import br.gov.frameworkdemoiselle.annotation.PreviousView;
import br.gov.frameworkdemoiselle.stereotype.ViewController;
import br.gov.frameworkdemoiselle.template.AbstractEditPageBean;
import br.gov.frameworkdemoiselle.transaction.Transactional;

@ViewController
@PreviousView("./recebimento_list.jsf")
public class RecebimentoEditMB extends AbstractEditPageBean<Recebimento, Long> {

	private static final long serialVersionUID = 1L;

	private Map<Pedido,Boolean> checkMap = new HashMap<Pedido,Boolean>();

	private List<Pedido> listaPedidos;
	
	private List<Recebimento> listaRecebimentos;

	public List<Recebimento> getListaRecebimentos() {
		if (this.getCliente() != null) {
			listaRecebimentos = recebimentoBC.consultarRecebimento(this.getCliente(), null, null, null, null);
		} else {
			listaRecebimentos = new ArrayList<Recebimento>();
		}
		return listaRecebimentos;
	}

	public void setListaRecebimentos(List<Recebimento> listaRecebimentos) {
		this.listaRecebimentos = listaRecebimentos;
	}

	public BigDecimal getValorDiferenca() {
		BigDecimal pedidos = getValorPedidos();
		if (pedidos == null) {
			pedidos = BigDecimal.ZERO;
		}
		BigDecimal recebimentos = getValorRecebimentos();
		if (recebimentos == null) {
			recebimentos = BigDecimal.ZERO;
		}
		
		return recebimentos.subtract(pedidos);
	}

	public BigDecimal getValorPedidosCancelado() {
		BigDecimal valorPedidos = BigDecimal.ZERO;
		if (this.getCliente() != null ) {
			this.getListaPedidos();
			List<Pedido> pedidos = listaPedidos;
			for (Pedido p : pedidos) {
				if (p.getStatusPedido().getId().equals(StatusPedido.CANCELADO)) {
					valorPedidos = valorPedidos.add(p.getValorTotalPedido());
					
				}
			}
		}
		return valorPedidos;
	}
	
	public BigDecimal getValorPedidos() {
		BigDecimal valorPedidos = BigDecimal.ZERO;
		if (this.getCliente() != null ) {
			this.getListaPedidos();
			List<Pedido> pedidos = listaPedidos;
			for (Pedido p : pedidos) {
				if (!p.getStatusPedido().getId().equals(StatusPedido.CANCELADO)) {
					valorPedidos = valorPedidos.add(p.getValorTotalPedido());
					
				}
			}
		}
		return valorPedidos;
	}


	public BigDecimal getValorRecebimentos() {
		BigDecimal valorRecebimentos = BigDecimal.ZERO;
		if (this.getCliente() != null ) {
			this.getListaRecebimentos();
			List<Recebimento> rs = listaRecebimentos;
			for (Recebimento r : rs) {
				valorRecebimentos = valorRecebimentos.add(r.getValorTotalRecebimento());
			}
		}
		return valorRecebimentos;
	}

	public BigDecimal getValorRecebimentosConferido() {
		BigDecimal  valorRecebimentos = BigDecimal.ZERO;
		if (this.getCliente() != null ) {
			this.getListaRecebimentos();
			List<Recebimento> rs = listaRecebimentos;
			for (Recebimento r : rs) {
				if (r.getConferido()) {
					valorRecebimentos = valorRecebimentos.add(r.getValorTotalRecebimento());
				}
			}
		}
		return valorRecebimentos;
	}

	@Inject
	private RecebimentoBC recebimentoBC;
	
	@Inject
	private PedidoBC pedidoBC;
	
	@Inject
	private ClienteBC clienteBC;
	private List<SelectItem> clientes;
	private Long cliente;

	public List<SelectItem> getClientes() {
		clientes = new ArrayList<SelectItem>();
		List<Cliente> lista = clienteBC.findAll();
		for (Cliente obj: lista) {
			clientes.add(new SelectItem(obj.getId() , obj.getNome()));
		}
		return clientes;
	}

	public void setClientes(List<SelectItem> clientes) {
		this.clientes = clientes;
	}

	public Long getCliente() {
		if(cliente == null && this.getBean().getCliente() != null)
			cliente = this.getBean().getCliente().getId();
		return cliente;
	}

	public void setCliente(Long cliente) {
		this.cliente = cliente;
	}

	@Inject
	private UsuarioBC usuarioBC;
	private List<SelectItem> usuarios;
	private Long usuario;

	public List<SelectItem> getUsuarios() {
		usuarios = new ArrayList<SelectItem>();
		boolean admin = false;
		ContextoUsuario usuario = (ContextoUsuario)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(ConstantesMensagem.CONTEXTO_USUARIO_SESSAO);
		if (usuario != null) {
			for (Perfil perfil :usuario.getUsuario().getListaPerfil()) {
				if (perfil.getId().equals(Perfil.PERFIL_ADM)){
					admin = true;
				}
			}
			
		}
		if (admin) {
			List<Usuario> lista = usuarioBC.findAll();
			for (Usuario obj: lista) {
				usuarios.add(new SelectItem(obj.getId() , obj.getNome()));
			}
		} else {
			usuarios.add(new SelectItem(usuario.getUsuario().getId() , usuario.getUsuario().getNome()));
		}
		return usuarios;
	}

	public void setUsuarios(List<SelectItem> usuarios) {
		this.usuarios = usuarios;
	}

	public Long getUsuario() {
		return usuario;
	}

	public void setUsuario(Long usuario) {
		this.usuario = usuario;
	}
	
	@Inject
	private FormaRecebimentoBC formaRecebimentoBC;
	private List<SelectItem> formaRecebimentos;
	private Long formaRecebimento;

	public List<SelectItem> getFormaRecebimentos() {
		formaRecebimentos = new ArrayList<SelectItem>();
		List<FormaRecebimento> lista = formaRecebimentoBC.findAll();
		for (FormaRecebimento obj: lista) {
			formaRecebimentos.add(new SelectItem(obj.getId() , obj.getDescricao()));
		}

		return formaRecebimentos;
	}

	public void setFormaRecebimentos(List<SelectItem> formaRecebimentos) {
		this.formaRecebimentos = formaRecebimentos;
	}

	public Long getFormaRecebimento() {
		if(formaRecebimento == null && this.getBean().getFormaRecebimento() != null)
			formaRecebimento = this.getBean().getFormaRecebimento().getId();
		return formaRecebimento;
	}

	public void setFormaRecebimento(Long formaRecebimento) {
		this.formaRecebimento = formaRecebimento;
	}

	@Override
	@Transactional
	public String delete() {
		this.recebimentoBC.delete(getId());
		return getPreviousView();
	}

	public boolean montaObjeto() {
		if(!this.isUpdateMode()) {
			if (FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(ConstantesMensagem.CONTEXTO_USUARIO_SESSAO) != null) {
				ContextoUsuario contexto = (ContextoUsuario) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(ConstantesMensagem.CONTEXTO_USUARIO_SESSAO);
				this.getBean().setUsuario(contexto.getUsuario());
			}
		}
		
		if(this.getCliente() != null)
			this.getBean().setCliente(this.clienteBC.load(this.getCliente()));

		if(this.getFormaRecebimento()  != null)
			this.getBean().setFormaRecebimento(this.formaRecebimentoBC.load(this.getFormaRecebimento()));

		getBean().setListaPedido(getSelected());

		return true;
	}	

	@Override
	@Transactional
	public String insert() {
		if (montaObjeto()) { 
			this.recebimentoBC.insert(getBean());
			return getPreviousView();
		} else {
			return getCurrentView();
		}
	}
	
	@Override
	@Transactional
	public String update() {
		if (montaObjeto()) { 
			this.recebimentoBC.update(getBean());
			return getPreviousView();
		} else {
			return getCurrentView();
		}
	}

	
	
	@Override
	protected Recebimento handleLoad(Long id) {
		setBean(this.recebimentoBC.load(id));

		getListaPedidos();
		
		if(this.getBean() != null && this.getBean().getListaPedido() != null) {
			for (Pedido pa : listaPedidos) {
				for (Pedido paCadastrado : this.getBean().getListaPedido()) {
					if (pa.getId().equals(paCadastrado.getId())) {
						checkMap.put(pa, new Boolean(true));
					}
				}
				if (checkMap.get(pa) == null ) {
					checkMap.put(pa, new Boolean(false));
				}
			}
		}
		
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("recebimento", this.getBean());
		
		return this.getBean();
	}
	
	public List<Pedido> getListaPedidos() {
		listaPedidos = new ArrayList<Pedido>();
		if (this.getCliente() != null) {
			listaPedidos = this.pedidoBC.consultarPedidos(null, null, this.getCliente(), null, null, null, null, null, null, null, null, null);
		} else {
			listaPedidos = new ArrayList<Pedido>();
		}
		return listaPedidos;
	}

	public Map<Pedido, Boolean> getCheckMap() {
		return checkMap;
	}
	
	public List<Pedido> getSelected() {
		List<Pedido> result = new ArrayList<Pedido>();
		
	    for (Entry<Pedido,Boolean> entry : checkMap.entrySet()) {
	        if (entry.getValue()) {
	            result.add(entry.getKey());
	        }
	    }
	    return result;
	}
	
	public void calcularValor() {
		if (this.getBean().getValorTotalRecebimento() == null) {
			this.getBean().setValorTotalRecebimento(BigDecimal.TEN);
		}
		
		BigDecimal valor = BigDecimal.ZERO;
		for (Pedido  pedido : getSelected()) {
			valor = valor.add(pedido.getValorTotalPedido());
		}
		this.getBean().setValorTotalRecebimento(valor);
	}
	
	public void postProcessXLS(Object document) {
		
		HSSFWorkbook wb = (HSSFWorkbook) document;
		HSSFSheet sheet = wb.getSheetAt(0);
		
		/******************** HEADER **********************/		
		CellStyle headerStyle = wb.createCellStyle();
		Font headerFont = wb.createFont();
		headerFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
		headerFont.setColor(HSSFColor.BLUE.index);
		headerStyle.setFont(headerFont);
		headerStyle.setAlignment(CellStyle.ALIGN_CENTER);
		 
		Row headerRow = sheet.getRow(0);
		int cont = 0; 
		for (Cell cell : headerRow) {
			cell.setCellStyle(headerStyle);
			if (0 == cont) {
				cell.setCellValue("Código Pedido");
			} else if (cont ==1) {
				cell.setCellValue("Usuário");
			} else if (cont ==2) {
				cell.setCellValue("Cliente");
			} else if (cont ==3) {
				cell.setCellValue("Data");
			} else if (cont ==4) {
				cell.setCellValue("Valor");
//			} else if (cont ==5) {
//				cell.setCellValue("Data Previsto Entrega");
//			} else if (cont ==6) {
//				cell.setCellValue("Status");
//			} else if (cont ==7) {
//				cell.setCellValue("Total Pedido");
			}
			cont++;
		}
		
		/******************** TOTAL **********************/
		CellStyle style = wb.createCellStyle();
		Font font = wb.createFont();
		font.setBoldweight(Font.BOLDWEIGHT_BOLD);
//		font.setColor(HSSFColor.ORANGE.index); 
		style.setFont(font);
		style.setAlignment(CellStyle.ALIGN_RIGHT);
		Row totalRow = sheet.createRow(sheet.getLastRowNum()+2);

		Cell cell1 = totalRow.createCell(1);

		cell1.setCellValue("Total");
		cell1.setCellStyle(style);
		Cell cell2 = totalRow.createCell(2);
		
		BigDecimal valor = BigDecimal.ZERO;
		List<Pedido> pedidos = this.getBean().getListaPedido();
		for (Pedido pedido : pedidos) {
			valor = valor.add(pedido.getValorTotalPedido());
		}
		
		cell2.setCellFormula(valor.toString());
		cell2.setCellStyle(style);

		//Ajuste do tamanho das colunas
		sheet.autoSizeColumn(0);
		sheet.autoSizeColumn(1);
//		sheet.autoSizeColumn(2);
//		sheet.autoSizeColumn(3);
	}

}